package com.rs.utils;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

import com.rs.game.World;
import com.rs.game.WorldObject;
import com.rs.game.WorldTile;
import com.rs.game.npc.NPC;
import com.rs.utils.Utils.EntityDirection;

public class NPCSpawning {

	/**
	 * Contains the custom npc spawning
	 */

	public static void spawnNPCS() {
		/***************************** GERYON II HOME *****************************************/
		World.spawnNPC(548, new WorldTile(2193, 3180, 0), -1, false, true); // Thessalia
		World.spawnNPC(881, new WorldTile(2179, 3173, 0), -1, false, EntityDirection.NORTHEAST); // Wizard 
		World.spawnNPC(456, new WorldTile(2180, 3172, 0), -1, false, EntityDirection.NORTHEAST); // Father Aerek
		World.spawnNPC(3374, new WorldTile(2189, 3171, 0), -1, false, EntityDirection.NORTHWEST); // Max
		World.spawnNPC(4585, new WorldTile(2185, 3178, 0), -1, false, EntityDirection.SOUTH); //teleporter
		World.spawnNPC(498, new WorldTile(2185, 3183, 0), -1, false, EntityDirection.SOUTH); // Banker
		World.spawnNPC(2593, new WorldTile(2186, 3185, 0), -1, false, EntityDirection.EAST); // Clerk
		World.spawnNPC(1419, new WorldTile(2183, 3185, 0), -1, false, EntityDirection.WEST); // Clerk
		World.spawnNPC(6988, new WorldTile(2181, 3192, 0), -1, false, EntityDirection.SOUTHEAST); // Pikkupstix
		World.spawnObject(new WorldObject(172, 10, 1, 2179, 3176, 0)); // Crystal Chest
		World.spawnObject(new WorldObject(19986, 10, 3, 2182, 3192, 0)); // Summ Obelisk
		World.spawnObject(new WorldObject(77030, 10, 0, 2185, 3192, 0)); // Small Summ obelisk
		World.spawnObject(new WorldObject(47173, 10, 0, 2183, 3183, 0)); // Ge booth
		World.spawnObject(new WorldObject(2562, 10, 2, 2188, 3171, 0)); // Catapult
		World.spawnObject(new WorldObject(-1, 10, 0, 2185, 3183, 0)); // Catapult
		World.spawnObject(new WorldObject(-1, 10, 0, 2184, 3183, 0)); // Catapult
		World.spawnObject(new WorldObject(-1, 10, 0, 2186, 3183, 0)); // Catapult
		//World.spawnNPC(9085, new WorldTile(2179, 3189, 0), 0, false); // Kuradal
		World.spawnNPC(14282, new WorldTile(2177, 3185, 0), 0, false, EntityDirection.SOUTHEAST); // Slayer veteran
		World.spawnNPC(2998, new WorldTile(2178, 3178, 0), 0, false, true); // Gambler
		World.spawnObject(new WorldObject(13199, 10, 0, 2182, 3171, 0)); // Altar at home
		World.spawnObject(new WorldObject(15477, 10, 1, 2175, 3180, 0)); // House Portal
		World.spawnNPC(4247, new WorldTile(2176, 3178, 0), 0, false, EntityDirection.NORTHEAST); // Estate Agent
		World.spawnNPC(30, new WorldTile(2191, 3173, 0), 0, false, EntityDirection.NORTHWEST); // Listen to musician
		World.spawnNPC(14912, new WorldTile(2191, 3175, 0), -1, false, EntityDirection.NORTH); // FredBinder
		World.spawnNPC(14943, new WorldTile(2179, 3189, 0), -1, false, EntityDirection.SOUTHEAST); // Druid Elementalist
		World.spawnNPC(15533, new WorldTile(2193, 3176, 0), -1, false, EntityDirection.NORTHWEST); // MinnieCoop
		World.spawnNPC(15582, new WorldTile(2192, 3175, 0), -1, false, EntityDirection.NORTHWEST); // HeyPresto
		World.spawnNPC(9047, new WorldTile(2189, 3190, 0), -1, false, EntityDirection.SOUTHWEST); // DonationManager.
		World.spawnNPC(13928, new WorldTile(2193, 3177, 0), 0, false, EntityDirection.NORTHWEST); // Artisan
		World.spawnNPC(520, new WorldTile(2194, 3177, 0), -1, false, EntityDirection.NORTH); // Shopkeeper (General Store)
		World.spawnNPC(4286, new WorldTile(2194, 3185, 0), 0, false, EntityDirection.SOUTHWEST); // Loyalty Manager		
		World.spawnNPC(9367, new WorldTile(2195, 3178, 0), 0, false, EntityDirection.WEST); // Loyalty Manager		
		World.spawnNPC(4965, new WorldTile(3499, 3621, 0), -1, false, EntityDirection.SOUTH); //Tool Leprechaun//Achievement capes
		World.spawnNPC(14414, new WorldTile(2188, 3191, 0), -1, false, EntityDirection.SOUTH); //Voting Manager


		World.spawnObject(new WorldObject(18615, 10, 1, 4762, 5895, 0));



		/***************************** HOME *****************************************/
		World.spawnNPC(8548, new WorldTile(4382, 5915, 0), -1, false, EntityDirection.NORTH); // Phoenix Guide
	//	World.spawnNPC(2240, new WorldTile(2835, 3857, 0), -1, false, EntityDirection.NORTH); // clerk
	//	World.spawnNPC(15876, new WorldTile(2832, 3859, 0), -1, false, EntityDirection.NORTH); // clerk

		World.spawnNPC(4965, new WorldTile(2824, 3867, 0), -1, false, EntityDirection.SOUTH); //Tool Leprechaun

		World.spawnNPC(548, new WorldTile(2823, 3862, 0), -1, false, EntityDirection.SOUTH); // Thessalia
		World.spawnNPC(14912, new WorldTile(2822, 3858, 0), -1, false, EntityDirection.EAST); // FredBinder
		World.spawnNPC(520, new WorldTile(2823, 3855, 0), -1, false, EntityDirection.NORTH); // Shopkeeper (General Store)
		World.spawnNPC(15533, new WorldTile(2822, 3859, 0), -1, false, EntityDirection.EAST); // MinnieCoop
		World.spawnNPC(15582, new WorldTile(2822, 3860, 0), -1, false, EntityDirection.EAST); // HeyPresto
		World.spawnNPC(14943, new WorldTile(2822, 3857, 0), -1, false, EntityDirection.EAST); // Druid Elementalist

		World.spawnNPC(4585, new WorldTile(2837, 3855, 0), 0, false, EntityDirection.NORTHWEST); // Voter
		World.spawnNPC(14282, new WorldTile(2836, 3864, 0), 0, false, EntityDirection.SOUTHWEST); // Sakirth
		World.spawnNPC(9085, new WorldTile(2838, 3861, 0), 0, false, EntityDirection.WEST); // Kuradal
		World.spawnNPC(13697, new WorldTile(2838, 3857, 0), 0, false, EntityDirection.WEST); // CaptainJute
		World.spawnNPC(13928, new WorldTile(2827, 3858, 0), 0, false, EntityDirection.EAST); // Artisan
		World.spawnNPC(2998, new WorldTile(2827, 3857, 0), 0, false, EntityDirection.EAST); // Gambler
		World.spawnNPC(4286, new WorldTile(2828, 3855, 0), 0, false, EntityDirection.NORTHEAST); // Loyalty Manager		
	//	World.spawnNPC(15872, new WorldTile(2841, 3859, 0), 0, false, true); // ?		
		
		World.spawnNPC(0, new WorldTile(3222, 3222, 0), 0, false, true); // Hans
		World.spawnNPC(7578, new WorldTile(2828, 3865, 0), 0, false, EntityDirection.SOUTHEAST); // Larry
		World.spawnNPC(519, new WorldTile(2827, 3861, 0), 0, false, EntityDirection.EAST); // Bob
		World.spawnNPC(4250, new WorldTile(2827, 3862, 0), 0, false, EntityDirection.EAST); // Sawmill Operator
		World.spawnNPC(14830, new WorldTile(5881, 4679, 1), 0, false, EntityDirection.EAST); // Char/Donator Zone
		World.spawnNPC(804, new WorldTile(3274, 3105, 0), 0, false, EntityDirection.EAST); // Tanner
		World.spawnNPC(804, new WorldTile(5886, 4673, 1), 0, false, EntityDirection.EAST); // Tanner (DZ)
		// World.spawnObject(new WorldObject(id, 10, direction, x, y, z), true);

		World.spawnObject(new WorldObject(13199, 10, 3, 2838, 3862, 0)); // Altar at home
		World.spawnObject(new WorldObject(13199, 10, 2, 5891, 4674, 1)); // Altar at dz
		World.spawnObject(new WorldObject(30624, 10, 0, 5880, 4661, 1)); // Blood altar at dz
		World.spawnObject(new WorldObject(172, 10, 1, 2827, 3860, 0));
		World.spawnObject(new WorldObject(13707, 10, 1, 2827, 3863, 0));
		World.spawnObject(new WorldObject(9759, 10, 0, 2569, 5732, 0));
		World.spawnObject(new WorldObject(42135, 10, 1, 1968, 3245, 0));
		World.spawnObject(new WorldObject(42135, 10, 1, 1967, 3245, 0));
		World.spawnObject(new WorldObject(42135, 10, 1, 1966, 3245, 0));
		World.spawnObject(new WorldObject(42148, 10, 1, 1807, 3219, 0));
		
		/*QUESTS*/
		World.spawnNPC(654, new WorldTile(3138, 3212, 0), 0, false, EntityDirection.SOUTH); // Shamus
		World.spawnNPC(208, new WorldTile(2567, 3463, 0), 0, false); // Captain Lawgof
		World.spawnNPC(209, new WorldTile(3016, 3448, 0), 0, false); // Nulodion
		World.spawnNPC(8526, new WorldTile(1888, 3179, 0), 0, true); // Zimberfizz
		
		/*PENGUINS*/
		World.spawnNPC(8110, new WorldTile(3225, 3371, 0), -1, true, true);
		World.spawnNPC(8109, new WorldTile(3216, 3399, 1), -1, true, true);
		World.spawnNPC(8108, new WorldTile(3201, 3433, 0), -1, true, true);
		World.spawnNPC(8107, new WorldTile(3175, 3408, 0), -1, true, true);
		World.spawnNPC(8106, new WorldTile(3158, 3489, 0), -1, true, true);
		World.spawnNPC(8105, new WorldTile(3228, 3475, 0), -1, true, true);
		World.spawnNPC(8104, new WorldTile(3253, 3487, 0), -1, true, true);
		
		/* BANK BOOTHS */
		World.spawnObject(new WorldObject(76274, 10, -3, 2830, 3869, 0));
		World.spawnObject(new WorldObject(76274, 10, -3, 2831, 3869, 0));
		World.spawnObject(new WorldObject(76274, 10, -3, 2832, 3869, 0));
		World.spawnObject(new WorldObject(76274, 10, -3, 2833, 3869, 0));
		World.spawnObject(new WorldObject(76274, 10, -3, 2834, 3869, 0));
		World.spawnObject(new WorldObject(76274, 10, -3, 2835, 3869, 0));
		World.spawnObject(new WorldObject(13612, 10, 1, 2832, 3871, 0)); 

		
		World.spawnNPC(498, new WorldTile(2833, 3870, 0), 0, false, EntityDirection.SOUTH); // Banker
		World.spawnNPC(498, new WorldTile(2832, 3870, 0), 0, false, EntityDirection.SOUTH); // Banker
		
		/* THIEVING STALLS */
		World.spawnObject(new WorldObject(4875, 10, 1, 2835, 3851, 0));
		World.spawnObject(new WorldObject(4876, 10, 1, 2835, 3850, 0));
		World.spawnObject(new WorldObject(4877, 10, 1, 2835, 3849, 0));
		World.spawnObject(new WorldObject(4878, 10, 1, 2835, 3848, 0));
		/* THIEVING STALLS */
		
		/* SUMMONING BANK CHEST */
		World.spawnObject(new WorldObject(27663, 10, -2, 2932, 3451, 0));// Bank chest
		/* SUMMONING BANK CHEST */
		
		// World.removeObject(new WorldObject(objectId, 10, 0, x, y, z), true);

		
		/***************************** DONATOR ZONE *********************************/
		World.spawnNPC(1552, new WorldTile(5895, 4684, 1), 0, true, EntityDirection.SOUTH); // Santa (Donator Shop)
		/***************************** DONATOR ZONE *********************************/
		/************************* SLAYER TOWER *************************************/
		//World.spawnNPC(id, tile, mapAreaNameHash, canBeAttackFromOutOfArea);
		World.spawnNPC(412, new WorldTile(3423, 3536, 0), 0, true); // Bat
		World.spawnNPC(412, new WorldTile(3418, 3536, 0), 0, true); // Bat
		World.spawnNPC(412, new WorldTile(3414, 3539, 0), 0, true); // Bat
		World.spawnNPC(412, new WorldTile(3412, 3536, 0), 0, true); // Bat
		World.spawnNPC(412, new WorldTile(3413, 3533, 0), 0, true); // Bat
		World.spawnNPC(412, new WorldTile(3407, 3536, 0), 0, true); // Bat
		/************************* SLAYER TOWER *************************************/
		
		/************************* TAVERLY DUNGEON **********************************/
		World.spawnNPC(82, new WorldTile(2932, 9796, 0), 0, true); // Lesser Demon
		World.spawnNPC(82, new WorldTile(2937, 9794, 0), 0, true); // Lesser Demon
		World.spawnNPC(82, new WorldTile(2931, 9800, 0), 0, true); // Lesser Demon
		World.spawnNPC(82, new WorldTile(2930, 9805, 0), 0, true); // Lesser Demon
		World.spawnNPC(82, new WorldTile(2927, 9803, 0), 0, true); // Lesser Demon
		World.spawnNPC(82, new WorldTile(2932, 9810, 0), 0, true); // Lesser Demon
		/************************* TAVERLY DUNGEON **********************************/
		
		/********************** DESERT STRYKEWYRMS **********************************/
		//World.spawnNPC(id, tile, mapAreaNameHash, canBeAttackFromOutOfArea);
		World.spawnNPC(9464, new WorldTile(3366, 3163, 0), -1, true);
		World.spawnNPC(9464, new WorldTile(3366, 3159, 0), -1, true);
		World.spawnNPC(9464, new WorldTile(3366, 3154, 0), -1, true);
		World.spawnNPC(9464, new WorldTile(3369, 3155, 0), -1, true);
		World.spawnNPC(9464, new WorldTile(3366, 3159, 0), -1, true);
		World.spawnNPC(9464, new WorldTile(3372, 3153, 0), -1, true);
		World.spawnNPC(9464, new WorldTile(3376, 3155, 0), -1, true);
		/********************** DESERT STRYKEWYRMS **********************************/
		
		World.spawnNPC(8629, new WorldTile(1888, 5127, 0), -1, true);
		World.spawnNPC(10479, new WorldTile(3161, 4278, 0), -1, true);
		World.spawnNPC(10479, new WorldTile(3161, 4275, 0), -1, true);
		World.spawnNPC(10479, new WorldTile(3161, 4273, 0), -1, true);
		World.spawnNPC(10479, new WorldTile(3161, 4270, 0), -1, true);
		World.spawnNPC(10479, new WorldTile(3161, 4267, 0), -1, true);
		World.spawnNPC(10479, new WorldTile(3161, 4265, 0), -1, true);
		World.spawnNPC(10479, new WorldTile(3161, 4263, 0), -1, true);
		World.spawnNPC(10479, new WorldTile(3161, 4262, 0), -1, true);
		World.spawnNPC(10479, new WorldTile(3161, 4261, 0), -1, true);
		World.spawnNPC(10479, new WorldTile(3153, 4251, 0), -1, true);
		World.spawnNPC(10479, new WorldTile(3156, 4249, 0), -1, true);
		World.spawnNPC(10479, new WorldTile(3172, 4261, 0), -1, true);
		World.spawnNPC(10479, new WorldTile(3173, 4268, 0), -1, true);

		World.spawnNPC(13335, new WorldTile(2182, 5669, 0), -1, true);

		World.spawnNPC(13460, new WorldTile(2704, 3642, 0), -1, true);
		World.spawnNPC(3334, new WorldTile(3135, 3739, 0), -1, true);

		// Khumn, mission giver
		World.spawnNPC(15867, new WorldTile(3145, 4656, 0), 0, false);

		// Polypore Dungeon Shop
		World.spawnNPC(875, new WorldTile(4724, 5466, 0), -1, false);

		/* Start of new home */
		/**************************************************************************/
		/**************************************************************************/
		World.spawnObject(new WorldObject(-1, 0, 0, 3671, 2976, 0));
		// Bankers
		World.spawnNPC(494, new WorldTile(3682, 2983, 0), -1, false, false);
		// Object spawning
//		World.spawnObject(new WorldObject(47120, 10, -1, 2651, 2653, 0), true);
		// Thieving stalls
		/**************************************************************************/
		/**************************************************************************/
		/* End of new Home */

		// Tzhaar
		World.spawnNPC(2625, new WorldTile(2617, 5132, 0), -1, false);
		World.spawnNPC(2614, new WorldTile(4666, 5082, 0), -1, false);

		/* Dungeoneering - Dungeon room objects */
		World.spawnObject(new WorldObject(49766, 10, 2, 89, 721, 0));
		World.spawnObject(new WorldObject(49768, 10, 2, 88, 721, 0));
		World.spawnObject(new WorldObject(49770, 10, 2, 87, 721, 0));
		World.spawnObject(new WorldObject(49772, 10, 2, 86, 721, 0));
		World.spawnObject(new WorldObject(49774, 10, 2, 85, 721, 0));

		// World.spawnNPC(4874, new WorldTile(4509, 5588, 0), -1, true, true);

		// Fishing SPOT spawnings!
		World.spawnNPC(327, new WorldTile(2604, 3419, 0), -1, true, true);
		World.spawnNPC(6267, new WorldTile(2605, 3420, 0), -1, true, true);
		World.spawnNPC(312, new WorldTile(2605, 3421, 0), -1, true, true);
		World.spawnNPC(313, new WorldTile(2604, 3422, 0), -1, true, true);
		World.spawnNPC(952, new WorldTile(2603, 3422, 0), -1, true, true);
		World.spawnNPC(327, new WorldTile(2604, 3423, 0), -1, true, true);
		World.spawnNPC(6267, new WorldTile(2605, 3424, 0), -1, true, true);
		World.spawnNPC(312, new WorldTile(2605, 3425, 0), -1, true, true);
		World.spawnNPC(327, new WorldTile(2599, 3419, 0), -1, true, true);
		World.spawnNPC(6267, new WorldTile(2598, 3422, 0), -1, true, true);
		World.spawnNPC(8864, new WorldTile(2590, 3419, 0), -1, true, true);
		World.spawnNPC(328, new WorldTile(2604, 3426, 0), -1, true, true);
		World.spawnNPC(329, new WorldTile(2603, 3426, 0), -1, true, true);

//		World.spawnObject(new WorldObject(38453, 10, -3, 4502, 5608, 0), true);// unlit beacon

		// Fishing spot
		World.spawnObject(new WorldObject(36786, 10, 2, 2587, 3422, 0));

		// Runecrafting skill ALTARS + NPC's + Banks
		World.spawnObject(new WorldObject(2478, 10, -2, 2600, 3155, 0));// 1-Air altar
		World.spawnObject(new WorldObject(2479, 10, -2, 2597, 3155, 0));// 2-Mind altar
		World.spawnObject(new WorldObject(2480, 10, -2, 2594, 3157, 0));// 3-Water altar
		World.spawnObject(new WorldObject(2481, 10, -2, 2594, 3160, 0));// 4-Earth altar
		World.spawnObject(new WorldObject(2482, 10, -2, 2594, 3163, 0));// 5-Fire altar
		World.spawnObject(new WorldObject(2483, 10, -2, 2594, 3166, 0));// 6-Body altar
		World.spawnObject(new WorldObject(2484, 10, -2, 2603, 3157, 0));// 7-Cosmic altar
		World.spawnObject(new WorldObject(2487, 10, -2, 2603, 3160, 0));// 8-Chaos altar
		World.spawnObject(new WorldObject(17010, 10, -2, 2603, 3163, 0));// 9-Astral altar
		World.spawnObject(new WorldObject(2486, 10, -2, 2603, 3166, 0));// 10-Nature altar
		World.spawnObject(new WorldObject(2485, 10, -2, 2600, 3168, 0));// 11-Law altar
		World.spawnObject(new WorldObject(2488, 10, -2, 2597, 3168, 0));// 12-Death altar
		World.spawnObject(new WorldObject(30624, 10, -2, 2510, 3169, 0));// 13-Blood altar
		World.spawnObject(new WorldObject(2489, 10, -2, 2513, 3169, 0));// 14-Soul altar
		World.spawnObject(new WorldObject(27663, 10, -1, 2599, 3165, 0));// Bank chest
		World.spawnObject(new WorldObject(27663, 10, -3, 2600, 3165, 0));// Bank chest
		World.spawnObject(new WorldObject(27663, 10, -1, 2599, 3164, 0));// Bank chest
		World.spawnObject(new WorldObject(27663, 10, -3, 2600, 3164, 0));// Bank chest
		World.spawnObject(new WorldObject(27663, 10, -1, 2599, 3163, 0));// Bank chest
		World.spawnObject(new WorldObject(27663, 10, -3, 2600, 3163, 0));// Bank chest
		World.spawnObject(new WorldObject(27663, 10, -1, 2599, 3162, 0));// Bank chest
		World.spawnObject(new WorldObject(27663, 10, -3, 2600, 3162, 0));// Bank chest
		World.spawnObject(new WorldObject(27663, 10, -1, 2599, 3161, 0));// Bank chest
		World.spawnObject(new WorldObject(27663, 10, -3, 2600, 3161, 0));// Bank chest
		World.spawnNPC(537, new WorldTile(2598, 3162, 0), -1, true, true);// Scavvo (rc shop)

		// summoning area NPC
		World.spawnNPC(6970, new WorldTile(2207, 5345, 0), -1, true, true);// Pikkupstix (summoning shops)

		World.spawnNPC(9085, new WorldTile(1738, 5313, 1), 0, false); // Kuradal

	}

	/**
	 * The NPC classes.
	 */
	private static final Map<Integer, Class<?>> CUSTOM_NPCS = new HashMap<Integer, Class<?>>();

	public static void npcSpawn() {
		int size = 0;
		boolean ignore = false;
		try {
			for (String string : FileUtilities.readFile("data/npcs/npcspawns.txt")) {
				if (string.startsWith("//") || string.equals("")) {
					continue;
				}
				if (string.contains("/*")) {
					ignore = true;
					continue;
				}
				if (ignore) {
					if (string.contains("*/")) {
						ignore = false;
					}
					continue;
				}
				String[] spawn = string.split(" ");
				@SuppressWarnings("unused")
				int id = Integer.parseInt(spawn[0]), x = Integer.parseInt(spawn[1]), y = Integer.parseInt(spawn[2]), z = Integer.parseInt(spawn[3]), faceDir = Integer.parseInt(spawn[4]);
				NPC npc = null;
				Class<?> npcHandler = CUSTOM_NPCS.get(id);
				if (npcHandler == null) {
					npc = new NPC(id, new WorldTile(x, y, z), -1, true, false);
				} else {
					npc = (NPC) npcHandler.getConstructor(int.class).newInstance(id);
				}
				if (npc != null) {
					WorldTile spawnLoc = new WorldTile(x, y, z);
					npc.setLocation(spawnLoc);
					//World.spawnNPC(npc.getId(), spawnLoc, -1, true, false);
					size++;
				}
			}
		} catch (NumberFormatException e1) {
			e1.printStackTrace();
		} catch (IllegalArgumentException e1) {
			e1.printStackTrace();
		} catch (SecurityException e1) {
			e1.printStackTrace();
		} catch (IOException e1) {
			e1.printStackTrace();
		} catch (InstantiationException e1) {
			e1.printStackTrace();
		} catch (IllegalAccessException e1) {
			e1.printStackTrace();
		} catch (InvocationTargetException e1) {
			e1.printStackTrace();
		} catch (NoSuchMethodException e1) {
			e1.printStackTrace();
		}
		Logger.log("Loaded " + size + " custom npc spawns!");
	}

}